#include "framelesswindow.h"
#include <QDebug>
#include <QGuiApplication>
#include <QPainter>
#include <QStyle>
#include <QStyleOption>
#include <QSysInfo>
#include <QWindow>

FramelessWindow::FramelessWindow(QWidget *parent) : QMainWindow(parent) {
    // 设置无边框
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);
    setAttribute(Qt::WA_Hover); // 启用悬停事件

    // 设置背景色
    setStyleSheet("background: white;");

    // 添加阴影
    setAttribute(Qt::WA_DontCreateNativeAncestors);
    HWND hwnd = reinterpret_cast<HWND>(winId());
    MARGINS margins = {1, 1, 1, 1};
    DwmExtendFrameIntoClientArea(hwnd, &margins);
    int value = 2;
    DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &value, sizeof(value));
    DwmSetWindowAttribute(hwnd, DWMWA_ALLOW_NCPAINT, &value, sizeof(value));

    DWORD style = GetWindowLong(hwnd, GWL_STYLE);
    SetWindowLong(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_BORDER);

    // 初始时更新窗口边距
    updateWindowMargins();
    // 保存初始几何信息
    m_normalGeometry = geometry();
}

void FramelessWindow::updateWindowCornerPreference() {
#ifdef Q_OS_WIN
    HWND hwnd = reinterpret_cast<HWND>(winId());

    // 根据窗口状态设置圆角
    DWORD cornerPreference;
    if (m_isMaximized) {
        // 最大化时禁用圆角
        cornerPreference = DWMWCP_DONOTROUND;
    } else {
        // 非最大化时使用默认圆角
        cornerPreference = DWMWCP_DEFAULT;
    }

    // 设置窗口圆角属性
    DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPreference, sizeof(cornerPreference));
#endif
}

void FramelessWindow::updateWindowMargins() {
#ifdef Q_OS_WIN
    HWND hwnd = reinterpret_cast<HWND>(winId());

    if (m_isMaximized) {
        // 最大化时：清除 DWM 扩展边距
        const MyMargins shadow = {0, 0, 0, 0};
        DwmExtendFrameIntoClientArea(hwnd, reinterpret_cast<const MARGINS *>(&shadow));

        // 禁用 DWM 非客户区渲染
        DWORD ncrp = 1; // DWMNCRP_DISABLED
        DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(ncrp));

        // 修复最大化窗口边距问题
        setContentsMargins(0, 0, 0, 0);
    } else {
        // 非最大化时：恢复边距和渲染
        const MyMargins shadow = {1, 1, 1, 1};
        DwmExtendFrameIntoClientArea(hwnd, reinterpret_cast<const MARGINS *>(&shadow));

        DWORD ncrp = DWMNCRP_ENABLED;
        DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(ncrp));

        setContentsMargins(1, 1, 1, 1);
    }

    // 更新圆角设置
    updateWindowCornerPreference();
#endif
}

QScreen *FramelessWindow::currentScreen() const {
    // 获取当前窗口所在的屏幕（支持多显示器）
    QPoint center = geometry().center();
    QScreen *screen = QApplication::screenAt(center);
    return screen ? screen : QApplication::primaryScreen();
}

void FramelessWindow::showMaximized() {
    // 保存当前几何信息
    m_normalGeometry = geometry();

    // 获取当前窗口所在屏幕
    QScreen *screen = QGuiApplication::screenAt(geometry().center());
    if (!screen) {
        screen = QGuiApplication::primaryScreen();
    }

    if (screen) {
        // 设置窗口为屏幕的可用区域
        QRect desktopRect = screen->availableGeometry();
        setGeometry(desktopRect);
    }

    // 更新状态和边距
    m_isMaximized = true;
    updateWindowMargins();
    emit windowStateChanged();
}

void FramelessWindow::showNormal() {
    // 恢复窗口到保存的几何信息
    setGeometry(m_normalGeometry);

    // 更新状态和边距
    m_isMaximized = false;
    updateWindowMargins();
    emit windowStateChanged();
}

void FramelessWindow::showMinimized() { QMainWindow::showMinimized(); }

bool FramelessWindow::isMaximized() const { return m_isMaximized; }

void FramelessWindow::setTitleBar(QWidget *titleBar) {
    if (this->titleBar) {
        this->titleBar->removeEventFilter(this);
    }
    this->titleBar = titleBar;
    if (titleBar) {
        titleBar->installEventFilter(this);
    }
    setMenuWidget(titleBar);
}

bool FramelessWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) {
    if (eventType == "windows_generic_MSG") {
        return handleWinEvent(static_cast<MSG *>(message), result);
    }
    return false;
}

bool FramelessWindow::handleWinEvent(void *message, long *result) {
#ifdef Q_OS_WIN
    MSG *msg = static_cast<MSG *>(message);
    switch (msg->message) {
    case WM_NCCALCSIZE: {
        *result = 0;
        return true;
        break;
    }
    case WM_GETMINMAXINFO: {
        // 确保窗口最大化时覆盖任务栏
        MINMAXINFO *minMaxInfo = reinterpret_cast<MINMAXINFO *>(msg->lParam);
        HWND hwnd = reinterpret_cast<HWND>(winId());

        // 获取窗口当前所在显示器
        HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
        if (monitor) {
            MONITORINFO monitorInfo;
            monitorInfo.cbSize = sizeof(MONITORINFO);
            GetMonitorInfo(monitor, &monitorInfo);

            // 使用显示器的可用工作区域
            RECT workRect = monitorInfo.rcWork;
            minMaxInfo->ptMaxPosition.x = workRect.left;
            minMaxInfo->ptMaxPosition.y = workRect.top;
            minMaxInfo->ptMaxSize.x = workRect.right - workRect.left;
            minMaxInfo->ptMaxSize.y = workRect.bottom - workRect.top;
        } else {
            // 回退到主显示器
            QScreen *screen = QApplication::primaryScreen();
            if (screen) {
                QRect availableGeometry = screen->availableGeometry();
                minMaxInfo->ptMaxPosition.x = availableGeometry.x();
                minMaxInfo->ptMaxPosition.y = availableGeometry.y();
                minMaxInfo->ptMaxSize.x = availableGeometry.width();
                minMaxInfo->ptMaxSize.y = availableGeometry.height();
            }
        }

        // 设置最小尺寸
        qreal dpi = devicePixelRatioF();
        minMaxInfo->ptMinTrackSize.x = minimumWidth() * dpi;
        minMaxInfo->ptMinTrackSize.y = minimumHeight() * dpi;
        *result = 0;
        return true;
    }
    case WM_NCHITTEST: {
        // 处理非客户区命中测试以支持调整大小和Aero Snap
        const LONG border_width = m_nBorderWidth;
        RECT window_rect;
        GetWindowRect(reinterpret_cast<HWND>(winId()), &window_rect);

        long x = GET_X_LPARAM(msg->lParam); // 物理x坐标
        long y = GET_Y_LPARAM(msg->lParam); // 物理y坐标

        // 1. 转换物理坐标为逻辑坐标（关键修复）
        qreal dpr = this->devicePixelRatioF(); // 获取当前DPI缩放比例
        int logicalX = static_cast<int>(x / dpr);
        int logicalY = static_cast<int>(y / dpr);
        QPoint globalLogicalPos(logicalX, logicalY);

        // 2. 计算鼠标在窗口内的逻辑坐标
        QPoint pos = mapFromGlobal(globalLogicalPos);
        int local_x = pos.x(); // 窗口内逻辑x
        int local_y = pos.y(); // 窗口内逻辑y

        // 3. 边缘和角落判断（使用逻辑坐标）
        bool left = (local_x < border_width);
        bool right = (local_x > width() - border_width); // width()是逻辑宽度
        bool top = (local_y < border_width);
        bool bottom = (local_y > height() - border_width); // height()是逻辑高度

        // 处理角落
        if (left && top) {
            *result = HTTOPLEFT;
            return true;
        } else if (right && top) {
            *result = HTTOPRIGHT;
            return true;
        } else if (left && bottom) {
            *result = HTBOTTOMLEFT;
            return true;
        } else if (right && bottom) {
            *result = HTBOTTOMRIGHT;
            return true;
        }

        // 处理边缘
        if (left) {
            *result = HTLEFT;
            return true;
        } else if (right) {
            *result = HTRIGHT;
            return true;
        } else if (top) {
            *result = HTTOP;
            return true;
        } else if (bottom) {
            *result = HTBOTTOM;
            return true;
        }

        // 4. 标题栏区域判断（使用逻辑坐标）
        if (titleBar) {
            QPoint titlePos = titleBar->mapFromParent(pos);
            if (titleBar->rect().contains(titlePos)) {
                QWidget *child = titleBar->childAt(titlePos);
                if (!child || child == titleBar) {
                    *result = HTCAPTION;
                    return true;
                }
            }
        }

        break;
    }
    // 添加双击非客户区消息处理
    case WM_NCLBUTTONDBLCLK: {
        // 判断双击区域是否为标题栏（HTCAPTION）
        if (msg->wParam == HTCAPTION) {
            // 触发自定义最大化/还原逻辑
            if (m_isMaximized) {
                showNormal();
            } else {
                showMaximized();
            }
            *result = 0;
            return true; // 拦截系统默认处理
        }
        break;
    }
    case WM_SIZE: {
        // 不再处理WM_SIZE消息中的最大化状态
        break;
    }
    }
#endif
    return false;
}

bool FramelessWindow::event(QEvent *event) {
    // 处理窗口状态变化
    if (event->type() == QEvent::WindowStateChange) {
        // 忽略Qt的窗口状态变化，使用我们自己的状态管理
        return true;
    }
    return QMainWindow::event(event);
}

void FramelessWindow::mousePressEvent(QMouseEvent *event) {
    // 仅处理非Windows平台的拖动
#ifndef Q_OS_WIN
    if (event->button() == Qt::LeftButton && titleBar &&
        titleBar->rect().contains(titleBar->mapFromGlobal(event->globalPos()))) {
        isDragging = true;
        dragPosition = event->globalPos() - frameGeometry().topLeft();
        event->accept();
        return;
    }
#endif
    QMainWindow::mousePressEvent(event);
}

void FramelessWindow::mouseMoveEvent(QMouseEvent *event) {
    if (isDragging) {
        // 窗口拖动
        move(event->globalPos() - dragPosition);
        event->accept();
    } else {
        // 更新鼠标光标样式
#ifdef Q_OS_WIN
        HWND hwnd = reinterpret_cast<HWND>(winId());
        POINT pt = {event->globalPos().x(), event->globalPos().y()};
        LRESULT hit = SendMessage(hwnd, WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y));
        updateCursor(hit);
#endif
    }
    QMainWindow::mouseMoveEvent(event);
}

void FramelessWindow::mouseReleaseEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton && isDragging) {
        isDragging = false;
        event->accept();
    } else {
        QMainWindow::mouseReleaseEvent(event);
    }
}

void FramelessWindow::updateCursor(int hitTestResult) {
#ifdef Q_OS_WIN
    switch (hitTestResult) {
    case HTTOP:
    case HTBOTTOM:
        setCursor(Qt::SizeVerCursor);
        break;
    case HTLEFT:
    case HTRIGHT:
        setCursor(Qt::SizeHorCursor);
        break;
    case HTTOPLEFT:
    case HTBOTTOMRIGHT:
        setCursor(Qt::SizeFDiagCursor);
        break;
    case HTTOPRIGHT:
    case HTBOTTOMLEFT:
        setCursor(Qt::SizeBDiagCursor);
        break;
    case HTCAPTION:
    case HTCLIENT:
    default:
        setCursor(Qt::ArrowCursor);
    }
#endif
}

// void FramelessWindow::mouseDoubleClickEvent(QMouseEvent *event) {
//     if (titleBar && titleBar->rect().contains(titleBar->mapFromGlobal(event->globalPos()))) {
//         // 双击标题栏切换最大化/正常状态
//         if (m_isMaximized) {
//             showNormal();
//         } else {
//             showMaximized();
//         }
//         event->accept();
//         return;
//     }
//     QMainWindow::mouseDoubleClickEvent(event);
// }

void FramelessWindow::changeEvent(QEvent *event) {
    if (event->type() == QEvent::WindowStateChange) {
        // 忽略Qt的窗口状态变化事件
        return;
    }
    QMainWindow::changeEvent(event);
}

void FramelessWindow::paintEvent(QPaintEvent *event) {
    QMainWindow::paintEvent(event);

    // 绘制背景
    QStyleOption opt;
    opt.initFrom(this);
    QPainter painter(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);

    // 只在非最大化状态绘制边框
    if (!m_isMaximized) {
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(QColor("#e0e0e0"), 1));
        painter.drawRect(rect().adjusted(0, 0, -1, -1));
    }
}

bool FramelessWindow::eventFilter(QObject *obj, QEvent *event) {
    // 标题栏区域的事件处理
    if (obj == titleBar) {
        switch (event->type()) {
        case QEvent::MouseButtonPress:
            mousePressEvent(static_cast<QMouseEvent *>(event));
            return true;
        case QEvent::MouseMove:
            mouseMoveEvent(static_cast<QMouseEvent *>(event));
            return true;
        case QEvent::MouseButtonRelease:
            mouseReleaseEvent(static_cast<QMouseEvent *>(event));
            return true;
        case QEvent::MouseButtonDblClick:
            mouseDoubleClickEvent(static_cast<QMouseEvent *>(event));
            return true;
        default:
            break;
        }
    }
    return QMainWindow::eventFilter(obj, event);
}